﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;

using Warehouse.Service.Data;
using Warehouse.Silverlight.Core.Infrastructure.Components;
using Warehouse.Silverlight.Core.Infrastructure.Events;
using Warehouse.Silverlight.Core.Infrastructure.ViewModels;
using Warehouse.Silverlight.Modules.Main.Models;

namespace Warehouse.Silverlight.Modules.Main.ViewModels
{
    [Export]
    public class ProductListViewModel : ViewModel
    {
        private readonly IProductListModel _productListModel;
        private readonly IEventAggregator _eventAggregator;
        private IEnumerable<Product> _products;
        private Product _selectedProduct;

        [ImportingConstructor]
        public ProductListViewModel(IProductListModel productListModel, IEventAggregator eventAggregator)
        {
            _productListModel = productListModel;
            _eventAggregator = eventAggregator;

            Initialize();
        }

        // Override
        protected override void Initialize()
        {
            this.PropertyChanged += new PropertyChangedEventHandler(ProductListViewModel_PropertyChanged);

            _productListModel.PropertyChanged += new PropertyChangedEventHandler(_productListModel_PropertyChanged);
            _productListModel.GetProductsComplete += new EventHandler<EntityResultsArgs<Product>>(_productListModel_GetProductsComplete);
            _productListModel.GetProductsByCodeOrNameComplete += new EventHandler<EntityResultsArgs<Product>>(_productListModel_GetProductsByCodeOrNameComplete);

            SetCommands();

            _eventAggregator.GetEvent<SearchParamsChangedEvent>().Subscribe(ChangeSearchParams);
        }

        public Product SelectedProduct
        {
            get { return _selectedProduct; }
            set
            {
                if (_selectedProduct != value)
                {
                    _selectedProduct = value;
                    RaisePropertyChanged(() => SelectedProduct);

                    if (_selectedProduct != null)
                    {
                        _eventAggregator.GetEvent<SelectedProductChangedEvent>().Publish(_selectedProduct.ProductId);
                    }
                }
            }
        }

        public IEnumerable<Product> Products
        {
            get { return _products; }
            private set
            {
                if (_products != value)
                {
                    _products = value;
                    RaisePropertyChanged(() => Products);
                }
            }
        }

        public DelegateCommand AddNewItemCommand { get; set; }
        public DelegateCommand EditItemCommand { get; set; }
        public DelegateCommand DeleteItemCommand { get; set; }

        #region EventAggregator

        public void ChangeSearchParams(Dictionary<string, object> newSearchParams)
        {
            //string s = "";
            //foreach (var item in newSearchParams)
            //{
            //    s += item.Key + ": " + item.Value.ToString() + "\n";
            //}
            //System.Windows.MessageBox.Show(s);
            
            //_productListModel.GetProductsAsync();
            _productListModel.GetProductsByCodeOrNameAsync(newSearchParams[ProductSearchParams.ProductCodeKey].ToString());
            
        }

        #endregion

        #region SetCommands

        private void SetCommands()
        {
            AddNewItemCommand = new DelegateCommand(
                () => AddNewItem(),
                () => CanAddNewItem());
            EditItemCommand = new DelegateCommand(
                () => EditItem(),
                () => CanEditItem());
            DeleteItemCommand = new DelegateCommand(
                () => DeleteItem());
        }

        private void AddNewItem()
        {
        }
        private bool CanAddNewItem()
        {
            return IsBusy == false;
        }

        private void EditItem()
        {
        }
        private bool CanEditItem()
        {
            return IsBusy == false;
        }

        private void DeleteItem()
        {
        }
        private bool CanDeleteItem()
        {
            return IsBusy == false;
        }

        #endregion

        #region private Helpers

        private void ProductListViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "IsBusy":
                    AddNewItemCommand.RaiseCanExecuteChanged();
                    EditItemCommand.RaiseCanExecuteChanged();
                    DeleteItemCommand.RaiseCanExecuteChanged();
                    break;
                default:
                    break;
            }
        }

        private void _productListModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "IsBusy":
                    //this.IsBusy = _productListModel.IsBusy;
                    AddNewItemCommand.RaiseCanExecuteChanged();
                    EditItemCommand.RaiseCanExecuteChanged();
                    DeleteItemCommand.RaiseCanExecuteChanged();
                    break;
                //case "HasErrors":
                //    this.HasError = _productListModel.HasErrors;
                default:
                    break;
            }
        }

        private void _productListModel_GetProductsComplete(object sender, EntityResultsArgs<Product> e)
        {
            if (!e.HasError)
            {
                this.Products = e.Results;
                _eventAggregator.GetEvent<SearchResultChangedEvent>().Publish(true);
            }
            else
            {
                //AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        private void _productListModel_GetProductsByCodeOrNameComplete(object sender, EntityResultsArgs<Product> e)
        {
            if (!e.HasError)
            {
                this.Products = e.Results;
                _eventAggregator.GetEvent<SearchResultChangedEvent>().Publish(true);
            }
            else
            {
                //AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }

        #endregion
    }
}
